package web.graficos.base;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import logic.Buscador;
import bean.juego.AccionBanderaJuego;
import bean.juego.Juego;
import bean.juego.JuegoCTF;
import bean.jugador.AccionesBandera;
import bean.jugador.Jugador;
import util.Pair;
import web.graficos.GraficosBandera;
import web.util.GeneradorEstadisticas;
import web.util.ProcesadorJuegos;

public class GraficosBanderaBase extends GraficosBase implements GraficosBandera {

	private List<Juego> listaJuegos;
	private static final Logger logger = Logger.getLogger(GraficosBanderaBase.class.getName());

	public static GraficosBanderaBase getInstancia() {
		return new GraficosBanderaBase();
	}

	GraficosBanderaBase() {
		this.listaJuegos = Buscador.getListaJuegos();
	}

	@Override
	public String matrixAccionBanderaPorMinuto(List<Jugador> jugadores, final AccionesBandera.Acciones accion) {

		ProcesadorJuegos procesador = new ProcesadorJuegos() {

			private Map<Jugador, Pair<Integer, Integer>> map = new HashMap<Jugador, Pair<Integer, Integer>>();

			@Override
			public void init(List<Jugador> jugadores) {
				for (Jugador jugador : jugadores) {
					this.map.put(jugador, new Pair<Integer, Integer>(0, 0));
				}
			}

			@Override
			public void procesarJuego(Juego juego, Jugador jugador) {
				if (juego instanceof JuegoCTF && juego.esJugador(jugador)) {
					Pair<Integer, Integer> pair = this.map.get(jugador);
					int segundosJugados = pair.getSecond();
					int muertes = pair.getFirst();

					JuegoCTF juegoCTF = (JuegoCTF) juego;

					List<AccionBanderaJuego> capturasPartido = juegoCTF.getAccionesBandera();

					for (AccionBanderaJuego accionBandera : capturasPartido) {
						if (accionBandera.getJugador().equals(jugador) && accionBandera.getAccion().equals(accion)) {
							muertes++;
						}
					}

					segundosJugados += juegoCTF.getTiempoEnSegundos();
					this.map.put(jugador, new Pair<Integer, Integer>(muertes, segundosJugados));
				}
			}

			@Override
			public Object getDato(Jugador jugador) {
				Pair<Integer, Integer> pair = this.map.get(jugador);
				int segundosJugados = pair.getSecond();
				int muertes = pair.getFirst();

				float puntosPorMinuto;
				if (segundosJugados > 0) {
					puntosPorMinuto = (float) 60 * muertes / segundosJugados;
				} else {
					puntosPorMinuto = 0;
				}

				return puntosPorMinuto;
			}
		};

		GeneradorEstadisticas generador = new GeneradorEstadisticas(procesador);
		String retorno = generador.procesar(jugadores, this.listaJuegos);

		return retorno;
	}

	@Override
	public String matrixEfectividadCapturasPartido(List<Jugador> jugadores) {

		ProcesadorJuegos procesador = new ProcesadorJuegos() {

			private Map<Jugador, Pair<Integer, Integer>> map = new HashMap<Jugador, Pair<Integer, Integer>>();

			@Override
			public void init(List<Jugador> jugadores) {
				for (Jugador jugador : jugadores) {
					this.map.put(jugador, new Pair<Integer, Integer>(0, 0));
				}
			}

			@Override
			public void procesarJuego(Juego juego, Jugador jugador) {
				if (juego instanceof JuegoCTF && juego.esJugador(jugador)) {
					Pair<Integer, Integer> pair = this.map.get(jugador);
					int banderasEncontradas = pair.getSecond();
					int banderasCapturadas = pair.getFirst();
					JuegoCTF juegoCTF = (JuegoCTF) juego;

					List<AccionBanderaJuego> capturasPartido = juegoCTF.getAccionesBandera();

					for (AccionBanderaJuego accionBandera : capturasPartido) {
						if (accionBandera.getJugador().equals(jugador)) {
							if (accionBandera.getAccion().equals(AccionesBandera.Acciones.CAPTURA)) {
								banderasCapturadas++;
							} else if (accionBandera.getAccion().equals(AccionesBandera.Acciones.ENCUENTRO)) {
								banderasEncontradas++;
							}
						}
					}

					this.map.put(jugador, new Pair<Integer, Integer>(banderasCapturadas, banderasEncontradas));
				}
			}

			@Override
			public Object getDato(Jugador jugador) {
				Pair<Integer, Integer> pair = this.map.get(jugador);
				int banderasEncontradas = pair.getSecond();
				int banderasCapturadas = pair.getFirst();

				float efectividad;
				if (banderasEncontradas > 0) {
					efectividad = (float) 100 * banderasCapturadas / banderasEncontradas;
				} else {
					efectividad = 0;
				}

				return efectividad;
			}
		};

		GeneradorEstadisticas generador = new GeneradorEstadisticas(procesador);
		String retorno = generador.procesar(jugadores, this.listaJuegos);

		return retorno;
	}
}
